/*
 * Created on 2005-3-12
 *
 */
package bma.common.langutil.bean.impl;

import java.lang.reflect.Method;

import bma.common.langutil.bean.AccessType;
import bma.common.langutil.core.DirectInvoker;
import bma.common.langutil.core.ExceptionUtil;

/**
 * 
 * @author guanzhong
 * @since 1.0 (imported from BMA.ESP Project)
 * 
 */
public class BeanListSimple extends BeanListAbstract {

	private Method addMethod;

	private Method getMethod;

	private Method setMethod;

	private Method removeMethod;

	private Method sizeMethod;

	public BeanListSimple(Class prototype) {
		super(prototype);
	}

	@Override
	public boolean accessible(AccessType type) {

		switch (type) {
		case INDEX_GET:
			return getMethod != null;
		case SIZE:
			return sizeMethod != null;
		case INDEX_REMOVE:
			return removeMethod != null;
		case INDEX_SET:
			return setMethod != null;
		case ADD:
			return addMethod != null;
		default:
			return false;
		}
	}

	@Override
	public void add(Object thisObject, Object value) {
		if (thisObject == null) {
			throw new NullPointerException("this object");
		}
		if (addMethod == null) {
			throw new NullPointerException("add[" + getPrototype() + "]");
		}

		try {
			DirectInvoker.invoke(thisObject, addMethod, new Object[] { value });
		} catch (Exception e) {
			throw ExceptionUtil.throwRuntime(e);
		}
	}

	@Override
	public Object get(Object thisObject, int index) {
		if (thisObject == null) {
			throw new NullPointerException("this object");
		}
		if (getMethod == null) {
			throw new NullPointerException("getIndex[" + getPrototype() + "]");
		}

		try {
			return DirectInvoker.invoke(thisObject, getMethod,
					new Object[] { new Integer(index) });
		} catch (Exception e) {
			throw ExceptionUtil.throwRuntime(e);
		}
	}

	@Override
	public int size(Object thisObject) {
		if (thisObject == null) {
			throw new NullPointerException("this object");
		}
		if (sizeMethod == null) {
			throw new NullPointerException("size[" + getPrototype() + "]");
		}

		try {
			return ((Integer) DirectInvoker
					.invoke(thisObject, sizeMethod, null)).intValue();
		} catch (Exception e) {
			throw ExceptionUtil.throwRuntime(e);
		}
	}

	@Override
	public void remove(Object thisObject, int index) {
		if (thisObject == null) {
			throw new NullPointerException("this object");
		}
		if (removeMethod == null) {
			throw new NullPointerException("remove[" + getPrototype() + "]");
		}

		try {
			DirectInvoker.invoke(thisObject, removeMethod,
					new Object[] { new Integer(index) });
		} catch (Exception e) {
			throw ExceptionUtil.throwRuntime(e);
		}
	}

	@Override
	public void set(Object thisObject, int index, Object value) {
		if (thisObject == null) {
			throw new NullPointerException("this object");
		}
		if (setMethod == null) {
			throw new NullPointerException("set[" + getPrototype() + "]");
		}

		try {
			DirectInvoker.invoke(thisObject, setMethod, new Object[] {
					new Integer(index), value });
		} catch (Exception e) {
			throw ExceptionUtil.throwRuntime(e);
		}
	}

	/**
	 * @return Returns the addMethod.
	 */
	public Method getAddMethod() {
		return addMethod;
	}

	/**
	 * @param addMethod
	 *            The addMethod to set.
	 */
	public void setAddMethod(Method addMethod) {
		this.addMethod = addMethod;
	}

	/**
	 * @return Returns the getMethod.
	 */
	public Method getGetMethod() {
		return getMethod;
	}

	/**
	 * @param getMethod
	 *            The getMethod to set.
	 */
	public void setGetMethod(Method getMethod) {
		this.getMethod = getMethod;
	}

	/**
	 * @return Returns the removeMethod.
	 */
	public Method getRemoveMethod() {
		return removeMethod;
	}

	/**
	 * @param removeMethod
	 *            The removeMethod to set.
	 */
	public void setRemoveMethod(Method removeMethod) {
		this.removeMethod = removeMethod;
	}

	/**
	 * @return Returns the setMethod.
	 */
	public Method getSetMethod() {
		return setMethod;
	}

	/**
	 * @param setMethod
	 *            The setMethod to set.
	 */
	public void setSetMethod(Method setMethod) {
		this.setMethod = setMethod;
	}

	/**
	 * @return Returns the sizeMethod.
	 */
	public Method getSizeMethod() {
		return sizeMethod;
	}

	/**
	 * @param sizeMethod
	 *            The sizeMethod to set.
	 */
	public void setSizeMethod(Method sizeMethod) {
		this.sizeMethod = sizeMethod;
	}

}
